from __future__ import print_function

from kivy.app import App
from kivy.properties import ObjectProperty, \
    NumericProperty, BooleanProperty, ListProperty
from kivy.uix.widget import Widget

from goblinoid.services.pumpthreads import FeedThread

from goblinoid.services.thread_queue import ThreadQueue


class ProfileService(Widget):
    pump_profile = ObjectProperty()
    activity_thread = ObjectProperty(None)
    thread_queue = ObjectProperty()
    activity_index = NumericProperty(0)
    batch_size = NumericProperty(20)
    cached_activities = ListProperty([])
    fetched_activities = ListProperty([])
    callback = ObjectProperty()
    already_refreshing = BooleanProperty(False)
    already_prefetching = BooleanProperty(False)

    def __init__(self, **kwargs):
        super(ProfileService, self).__init__(**kwargs)
        self.thread_queue = ThreadQueue(self.add_activity_item)

    def on_refresh(self, **kwargs):
        self.cached_activities = []
        self.activity_index = 0

    def update_profile(self, profile):
        self.pump_profile = profile

    def get_username(self):
        return unicode(self.pump_profile.username)

    def fetch_cached_posts(self):
        return self.cached_activities

    def set_callback(self, callback):
        self.callback = callback

    def fetch_posts(self, callback):
        # for now, we will only allow a single thread to run
        if not self.already_prefetching:
            print ("fetch_posts creating new thread")
            self.already_prefetching = True
            try:
                self.activity_thread = FeedThread(
                    self.thread_queue,
                    self.pump_profile.outbox.major,
                    self.activity_index,
                    self.batch_size)
                self.callback = callback
                self.activity_thread.start()
                self.activity_index += self.batch_size
            except KeyError:
                self.thread_queue.put('error', None)

    def add_activity_item(self):
            while True:
                if self.thread_queue.empty():
                    break
                key, activity = self.thread_queue.get()
                if key == 'done':
                    self.callback(self.fetched_activities)
                    self.cached_activities.extend(self.fetched_activities)
                    self.fetched_activities = []
                    self.already_prefetching = False
                    break
                elif key == 'end':
                    self.callback(key)
                    self.already_prefetching = False
                elif key == 'error':
                    self.callback(key)
                    self.already_prefetching = False
                    self.fetched_activities = []
                    break
                else:
                    self.fetched_activities.append(activity)
                    self.add_activity_to_manager(activity)

    def get_activity_from_index(self, index):
        return self.cached_activities[index]

    def add_activity_to_manager(self, activity):
        App.get_running_app().pump_service.activity_manager.add_activity(
            activity)
